package com.jpemartin.jgt;
import java.awt.*;
import java.net.URL;
import java.util.*;
import java.awt.image.*;

import javax.imageio.*;


/** Loads images, then displays an animation by looping through the images. 
 * 
 * The image can be in any format that Java can load; I recommend png.
 * 
 * The loading will work for files on disk, a jar file, or files on a web server
 * running an applet. Use relative names like "player.png" or "images/laser.png",
 * not "c:\program files\java\my images\cool picture.png"
 * 
 * If you have several objects using the same animation, it is more efficient
 * to create one DrawAnim and then clone() it rather than creating several: 
 * the clone shares data with the original so you save on memory, and the images 
 * are loaded only once so you save on initialization time.
 * 
 * @author jpmartin
 **/
public class DrawAnim implements Drawable, Cloneable {
 
    // that's where we'll keep the pictures
    BufferedImage[] _pic;
    //  which of the images is currently displayed
    int _current;
    // how many times should we display an image before moving to the
    // next one in the sequence
    int _delay;
    // number of times the image was displayed
    int _drawCount;
    // number of times we wrapped around
    int _loopCount;
    
    /** An animation that displays the given image. **/
    public DrawAnim(String imageName) throws java.io.IOException {
        _delay = 1;
        Vector<String> v = new Vector<String>();
        v.add(imageName);
        init(v,true);
    }
    
    /** An animation that displays the given image. 
     *  If keyed==true, all pixels that are the same color as 
     *  the top-left pixel will be made transparent. **/
    public DrawAnim(String imageName, boolean keyed) throws java.io.IOException {
        _delay = 1;
        Vector<String> v = new Vector<String>();
        v.add(imageName);
        init(v,keyed);
    }
    
    /** An animation that loops through the given images, each image is displayed "delay" times
     *  (or once if delay<1).
     *  
     */
    public DrawAnim(Collection imageNames, int delay) throws java.io.IOException {
        _delay = delay;
        init(imageNames,false); 
    }
    
    /** An animation that loops through the given images, each image is displayed "delay" times
     *  (or once if delay<1).
     *  If keyed==true, all pixels that are the same color as 
     *  the top-left pixel will be made transparent.
     */
    public DrawAnim(Collection imageNames, int delay, boolean keyed) throws java.io.IOException {
        _delay = delay;
        init(imageNames,keyed); 
    }
    
    /** back to original state (images loaded, beginning of anim loop). **/
    public void reset() {
        _drawCount=0;
        _current=0;
        _loopCount=0;
    }

    /** creates a clone of this object. The exception will never be thrown by this class. **/
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    /** draw one frame of the animation at the specified position **/
    public void draw(Graphics g, int x, int y) {
        g.drawImage(_pic[_current], x, y,null);
        if (++_drawCount>=_delay) {
            _drawCount=0;
            _current=(_current+1)%_pic.length;
            if (0==_current) _loopCount++;
        }
    }
    
    public int getWidth() {
       return _pic[_current].getWidth();
    }
    
    public int getHeight() {
       return _pic[_current].getHeight();
    }
    
    /** return the number of times every frame in the animation was drawn **/
    public int getLoopCount() {
       return _loopCount;
    }
    
    /** all one-time initialization, called by the ctor. **/
    protected void init(Collection imageNames,boolean keyed) throws java.io.IOException {
        _pic = new BufferedImage[imageNames.size()];
        int i=0;
        for (Object x : imageNames) {
            String name = (String)x;
            _pic[i]=loadPicture(name,keyed);
            i++;
        }
        // get to initial state
        reset();
    }
    
    /** load one picture */
    protected BufferedImage loadPicture(String name,boolean keyed) throws java.io.IOException {
        URL url = getClass().getClassLoader().getResource(name);
        if (null==url) throw new java.io.FileNotFoundException("Image not found: "+name);
        BufferedImage pic = ImageIO.read(url);
        if (keyed) pic=keyImage(pic);
        return pic;
    }
    
    /** make pixels transparent if same as top-left color **/
    protected BufferedImage keyImage(BufferedImage pic) {
        int w = pic.getWidth();
        int[] pixel = pic.getRGB(0,0,w,pic.getHeight(),null,0,w);
        // convention: top-left pixel indicates background color
        int background = pixel[0];
        for (int i=0; i<pixel.length; i++) {
            // make background pixels fully transparent
            if (pixel[i]==background) pixel[i]=0x00000000;
        }
        if (pic.getType()!=BufferedImage.TYPE_INT_ARGB) {
            // we re-create pic to make sure we're TYPE_INT_ARGB
            pic = new BufferedImage(w,pic.getHeight(),BufferedImage.TYPE_INT_ARGB);
        }
        pic.setRGB(0,0,w,pic.getHeight(),pixel,0,w);
        return pic;
    }
    
    
}
